#!/usr/bin/perl -w 

### Notes:
# The -T for security check would help to protect the script but was giving error and was removed.
# The arguments been used as parameterson external commands/scripts. For the arguments only hexadecimal and - are allowed. Feel free ADD extra protectiong.

use POSIX qw(strftime);

### Subroutines declarations ###

# Function to log and output warnings

$work_dir = '/Users/ecstv/fctranscode/';
$settingsdir = $work_dir.'/settings_short/';
$outputdir = $work_dir.'output/';
$ffmpeg_status_dir = $work_dir.'status/';
$log_file = $work_dir.'scripts.log';

$mediainfo = '/usr/local/bin/mediainfo';
### Subroutines declarations ###

# Function to log and output warnings

sub write_log{
        my $message = shift;
        my $cur_time = strftime "%d %b %Y (%H:%M:%S)", localtime;
        $message = $cur_time.' '.$message;
        open(my $lf_h, ">>", $log_file) or die("Could not open log file $log_file: $!");
        print $lf_h $message."\n";
        close($lf_h);
}
sub quick_warn{

        #TODO - Filter the 80xx messages so it is not forwarded to the user

        my $message = shift;
        # TODO - Uncomment this chomp($message);
        my $cur_time = strftime "%d %b %Y (%H:%M:%S)", localtime;
        $message = $cur_time.' '.$message;
        write_log($message);
        print $message;
}

# Function to log and output errors
#Add default "ERROR:" in the messages. Redo logs.
sub error_die{

        my $message = shift;
        # TODO: Uncomment this chomp($message);
        my $cur_time = strftime "%d %b %Y (%H:%M:%S)", localtime;
        $message = $cur_time.' '.$message;
        write_log($message);
        print $message."\n";
        exit(1);
}

### Start og main program ###

$log_file = '/tmp/monitor.pl.log';
$ffmpeg_status_files = $ffmpeg_status_dir.'*.status';


# Run Batch Monitor
my $cmd_str = "/Applications/Utilities/Batch\\ Monitor.app/Contents/MacOS/Batch\\ Monitor -clustername \"This Computer\"";

#print $cmd_str."\n";
$output = qx/$cmd_str/; # TODO - Check for errors
#print 'OUT:'.$output.':OUT';

open($rh, "<", \$output);

while($line = readline $rh){
	if ($line =~ /\A<jobStatus/){

		$line =~ /jobid=\"([[:xdigit:]-]{36})/;
	        $jobid = $1;

	        $line =~ /batchid=\"([[:xdigit:]-]{36})/;
		$batchid = $1;

		$line =~ /status=\"([\w\:\ ]+)\"/;
        	$status = $1;

	        $line =~ /percentComplete=\"(\d{1,3})\"/;
        	$percomp = $1;

		$line =~ /timeRemaining=\"([\w\(\)\ ]+)\"/;
	        $timerem = $1;

	        $line =~ /timeElapsed=\"([\w\(\)\ ]+)\"/;
        	$timeelap = $1;

		$jobs_status{ $jobid } = {
                		batchid => $batchid,
	                        status => $status,
        	                percomp => $percomp,
                	        timerem => $timerem,
                        	timeelap => $timeelap,
	                	};
       	}
}

foreach my $key (keys %jobs_status) {
	print "<jobStatus jobid=\"$key\" ";
	print "batchid=\"$jobs_status{$key}->{'batchid'}\" ";
	print "status=\"$jobs_status{$key}->{'status'}\" ";
        print "percentComplete=\"$jobs_status{$key}->{'percomp'}\" ";
	print "timeRemaining=\"$jobs_status{$key}->{'timerem'}\" ";
	print "timeElapsed=\"$jobs_status{$key}->{'timeelap'}\" ";
	print "/>\n";
}

# Retrieving ffmpeg job status

# Get list of all status files
@list = glob($ffmpeg_status_files);

foreach $file (@list){
	unless ($file =~ /\A.*\..*\.\d+\.status\z/) {next;}

	# Get input video duration

	$content = `tr '\\r' '\\n' < \"$file\" | head -20`;
	unless ($content =~ /Duration: (\d{2}):(\d{2}):(\d{2})\.(\d{2})/) {
		error_die("ERROR:3013: Information extracted from status file $file is invalid."); }

	$hours = $1;
	$mins = $2;
	$secs = $3;

	$input_secs = ((($hours*60)+$mins)*60)+$secs;

	# Get transcoding start time, input and output filename

	open $ch, "<", \$content;
	readline $ch;
	$t_start = readline $ch;
	$out_name = readline $ch;
	$out_name =~ s/\n//g;
	close $ch;

	# Get output video (so far transcoded) duration
	
	$content = `tr '\\r' '\\n' < \"$file\" |tail -4`;
	open $ch, "<", \$content;
	$end1 = readline $ch;
	readline $ch;
	readline $ch;
	$end4 = readline $ch;
	close $ch;

	if ($end4 =~ /\Aframe=.+time=(\d+)\..+bitrate.+/) {
		$output_secs = $1;
		$per_comp = ($output_secs/$input_secs) * 100;
		$t_current = time;
		$t_ela=$t_current-$t_start;
                $t_rem=($t_ela*(1-$per_comp/100))/($per_comp/100);
		$status = "Transcoding.";
	}
	elsif ($end1 =~ /\Aframe=.+time=(\d+)\..+bitrate.+/) {
		$output_secs = $1;
		$per_comp = ($output_secs/$input_secs) * 100;
		if ($end4 =~ /\AFINISH: (\d+)/) {
			 $t_current = $1;
			 $t_ela = $t_current-$t_start;
			 $t_rem=($t_ela*(1-$per_comp/100))/($per_comp/100);
			 $status = "Completed.";
		}
		elsif ($end4 =~ /\ACANCEL: (\d+)/) {
			$t_cancel = $1;
			$t_ela = $t_cancel-$t_start;
			$t_rem=($t_ela*(1-$per_comp/100))/($per_comp/100);
			$status = 'Cancelled.';
		}
	}
	else { error_die("ERROR:3013: Information extracted from status file $file is invalid.");}

	#if ($per_comp >= 100) {
	#	$t_ela=$t_current-$t_start;
	#	$t_rem="0";
	#	$status = "Completed."
	#}
	#else {
	#	$t_ela=$t_current-$t_start;
	#	$t_rem=($t_ela*(1-$per_comp/100))/($per_comp/100);
	#	$status = "Transcoding.";
	#}

	
	#print "Start: $t_start\n";
	#print "Current: $t_current\n";
	#print "IN sec: $input_secs\n";
	#print "OUT sec: $output_secs\n";
	#print "% : $per_comp\n";
	#print "Elapsed: $t_ela\n";
	#print "Remem: $t_rem\n";
	#print "Output: $out_name\n";
	
	@tEla_parts = gmtime($t_ela);
	@tRem_parts = gmtime($t_rem);

	print "<ffmpeg ";
	print "jobid=\"$file\" ";
	#print "out_file=\"$out_name\" ";
	#print "status_file=\"$file\" ";
	print "status=\"$status\" ";
	print "perComplete=\"$per_comp\" ";
	printf("timeElapsed=\"%d days, %02d:%02d:%02d\" ",@tEla_parts[7,2,1,0]);
	printf("timeRemaining=\"%d days, %02d:%02d:%02d\" ",@tRem_parts[7,2,1,0]);
	print "/>\n"; 
}

